<template>
  <q-list :class="classes || ''" class="medoc-search-cls row relative-position q-pt-sm q-pb-sm">
    <q-item v-for="column in columns" :key="column.field" :class="column.classes || 'col-12'"
            class="medoc-search-item q-pl-md q-pr-md q-pt-xs q-pb-xs">
      <q-item-section class="col-auto medoc-search-label">{{ column.label }}:</q-item-section>
      <q-item-section>
        <div class="medoc-search-main">
          <template v-for="chip in column.options" :key="getValue(chip, column.props)">
            <q-chip clickable dense outline square v-bind="chipAttrs(chip, column)"
                    @click.stop="handleSearch(chip, column)">
              {{ getLabel(chip, column.props) }}
            </q-chip>
          </template>
        </div>
      </q-item-section>
    </q-item>
    <q-resize-observer @resize="onResize"></q-resize-observer>
    <q-inner-loading :showing="loading">
      <q-spinner-ios color="primary" size="50px" />
    </q-inner-loading>
  </q-list>
</template>

<script setup>
import { throttle } from 'quasar'
import { computed, nextTick, onMounted, ref } from 'vue'
import { getLabel, getValue } from 'components/Global/Form/utils'

const props = defineProps({
  option: Object, loading: Boolean, modelValue: Object, searchSize: Object, labelWidth: [String, Number],
  classes: { type: String, default: 'bg-white border-8' }
})
const emits = defineEmits(['startSearch', 'update:modelValue', 'update:searchSize'])

const searchForm = ref({})

onMounted(() => {
  searchForm.value = props.modelValue || {}
})

const columns = computed(() => {
  const { column = [] } = props.option || {}
  return column.filter(el => el.search || el.options?.length)
})
const chipAttrs = computed(() => (chip, column) => {
  const { field, multiple, props } = column
  const valueList = multiple ? searchForm.value[field] || [] : [searchForm.value[field]]

  if (valueList.includes(getValue(chip, props))) {
    return { color: 'primary' }
  }
  return { color: 'dark', class: 'transparent-border' }
})

const onResize = size => emits('update:searchSize', size)
const handleRefresh = throttle(() => {
  emits('update:modelValue', searchForm.value)
  emits('startSearch')
}, 300)
const handleCascade = (cascade = '') => {
  return new Promise(resolve => {
    const keys = cascade.split(',').filter(el => el)
    nextTick(async () => {
      for (const key of keys) {
        const column = columns.value.find(el => el.field === key)
        if (!column) {
          searchForm.value[key] = void 0
          continue
        }
        const { multiple, props, clearable = true, options, cascade: cCascade = '' } = column
        if (multiple) {
          if (!clearable && options.length) searchForm.value[key] = [getValue(options[0], props)]
          else searchForm.value[key] = void 0
        } else {
          if (!clearable && options.length) searchForm.value[key] = getValue(options[0], props)
          else searchForm.value[key] = void 0
        }
        if (cCascade) await handleCascade(cCascade)
      }
      resolve()
    })
  })
}
const handleSearch = async (chip, column) => {
  const { field, multiple, props, clearable = true, cascade = '' } = column
  if (multiple) {
    searchForm.value[field] = searchForm.value[field] || []
    const index = searchForm.value[field].findIndex(el => el === getValue(chip, props))
    if (index > -1) {
      if (!clearable && searchForm.value[field].length === 1) return
      searchForm.value[field].splice(index, 1)
      await handleCascade(cascade)
      handleRefresh()
      return
    }
    searchForm.value[field].push(getValue(chip, props))
    await handleCascade(cascade)
    handleRefresh()
    return
  }
  if (searchForm.value[field] === getValue(chip, props)) {
    if (!clearable) return
    searchForm.value[field] = ''
  } else searchForm.value[field] = getValue(chip, props)
  await handleCascade(cascade)
  handleRefresh()
}
</script>